package server

import (
	"context"
	"log"
	"time"

	"gitee.com/yanwc/ebicycle/device/internal/field"
	"github.com/panjf2000/gnet"
)

type Device struct {
	Conn           gnet.Conn             // 设备socket链接
	CmdResult      chan interface{}      // 命令结果通道
	Busy           bool                  // 等待命令返回结果
	CmdMessageType uint8                 // 命令消息类型
	LastUpdatedAt  time.Time             // 心跳更新时间
	Version        field.FirmwareVersion // 对应固件版本号
	Imei           field.IMEI            // 设备Imei
	Imsi           field.IMSI            // 设备Imsi
	DeviceType     field.DeviceType      // 设备类型
}

func NewDevice(c gnet.Conn, v field.FirmwareVersion, imei field.IMEI, imsi field.IMSI, dt field.DeviceType) *Device {
	d := &Device{
		Conn:       c,
		Imei:       imei,
		Imsi:       imsi,
		DeviceType: dt,
	}

	return d
}

func (d *Device) SendCmd(ctx context.Context, name string, params interface{}) (interface{}, error) {
	err := d.Conn.AsyncWrite(nil)
	if err != nil {
		return nil, err
	}
	d.Busy = true
	select {
	case d := <-d.CmdResult:
		return d, nil
	case <-ctx.Done():
		d.Busy = false
		err := ctx.Err()
		log.Println(err)
		return nil, nil
	}
}

func (d *Device) AcceptCmdResult(msgType uint8, data interface{}) {
	if msgType == d.CmdMessageType && d.Busy {
		d.Busy = false
		d.CmdResult <- data
	}
}

func (d *Device) Notify(notifyType uint8) {
	// TODO 通知
}
